#include "DelayDeviceParamsSet.h"
#include "ui_DelayDeviceParamsSet.h"
#include <QMouseEvent>
#include <QDebug>
#include <cstring> // 用于memset
#include "DelayDevice.h"
/**
 * @brief 构造函数
 * @param pDelayDevice 延迟设备对象指针
 * @param parent 父窗口指针
 */
DelayDeviceParamsSet::DelayDeviceParamsSet(DelayDevice* pDelayDevice, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DelayDeviceParamsSet),
    m_isDragging(false),
    m_pDelayDevice(pDelayDevice),
    m_pADValueTimer(new QTimer(this))
{
    ui->setupUi(this);
    // 设置窗口为无边框
    this->setWindowFlags(Qt::FramelessWindowHint| Qt::Dialog);
    
    // 连接关闭按钮信号槽
    connect(ui->btnClose, &QToolButton::clicked, this, &DelayDeviceParamsSet::close);
    
    // 为标题栏设置鼠标跟踪
    ui->titleBar->setMouseTracking(true);
    ui->titleLabel->setMouseTracking(true);
    
    connect(pDelayDevice,&DelayDevice::updateADValue,this,&DelayDeviceParamsSet::onUpdateADValues);
    connect(pDelayDevice,&DelayDevice::updateArgs,this,[this](QObject* pSender)
    {
        if(this==pSender)
        {
            return;
        }
        updateUIValues();
    });


    // 添加表格输入验证
    
    // 1. 初始化延迟设置表格 (twInitDelaySettings)
    ui->twInitDelaySettings->item(0, 1)->setData(Qt::UserRole,RISE_EDGE_DELAY_T0);
    ui->twInitDelaySettings->item(1, 1)->setData(Qt::UserRole,FALL_EDGE_DELAY_T1);
    ui->twInitDelaySettings->item(2, 1)->setData(Qt::UserRole,RISE_EDGE_DELAY_T1);
    ui->twInitDelaySettings->item(3, 1)->setData(Qt::UserRole,FALL_EDGE_DELAY_T2);
    ui->twInitDelaySettings->item(4, 1)->setData(Qt::UserRole,RISE_EDGE_DELAY_T2);

    ui->twInitDelaySettings->item(0, 2)->setData(Qt::UserRole,RISE_EDGE_WIDTH_T0);
    ui->twInitDelaySettings->item(1, 2)->setData(Qt::UserRole,FALL_EDGE_WIDTH_T1);
    ui->twInitDelaySettings->item(2, 2)->setData(Qt::UserRole,RISE_EDGE_WIDTH_T1);
    ui->twInitDelaySettings->item(3, 2)->setData(Qt::UserRole,FALL_EDGE_WIDTH_T2);
    ui->twInitDelaySettings->item(4, 2)->setData(Qt::UserRole,RISE_EDGE_WIDTH_T2);

    // 2. 精延迟设置表格 (twFineDelaySettings)
    ui->twFineDelaySettings->item(0, 1)->setData(Qt::UserRole,PRECISE_DELAY_TIME_T0);
    ui->twFineDelaySettings->item(1, 1)->setData(Qt::UserRole,PRECISE_DELAY_TIME_T1);
    ui->twFineDelaySettings->item(2, 1)->setData(Qt::UserRole,PRECISE_DELAY_TIME_T2);
    ui->twFineDelaySettings->item(0, 2)->setData(Qt::UserRole,PRECISE_DELAY_WIDTH_T0);
    ui->twFineDelaySettings->item(1, 2)->setData(Qt::UserRole,PRECISE_DELAY_WIDTH_T1);
    ui->twFineDelaySettings->item(2, 2)->setData(Qt::UserRole,PRECISE_DELAY_WIDTH_T2);

    // 3. 电压和IO表格 (twVoltageIO)
    ui->twVoltageIO->item(0, 1)->setData(Qt::UserRole,AD_VALUE_1);
    ui->twVoltageIO->item(1, 1)->setData(Qt::UserRole,AD_VALUE_2);
    ui->twVoltageIO->item(0, 2)->setData(Qt::UserRole,DA_VALUE_1);
    ui->twVoltageIO->item(1, 2)->setData(Qt::UserRole,DA_VALUE_2);
    ui->twVoltageIO->item(0, 3)->setData(Qt::UserRole,IO_VALUE_1);
    ui->twVoltageIO->item(1, 3)->setData(Qt::UserRole,IO_VALUE_2);

    // 4. 为表格单元格添加编辑事件处理，实现实时验证
    connect(ui->twInitDelaySettings, &QTableWidget::cellChanged, this, &DelayDeviceParamsSet::onCellChanged);
    connect(ui->twFineDelaySettings, &QTableWidget::cellChanged, this, &DelayDeviceParamsSet::onCellChanged);
    connect(ui->twVoltageIO, &QTableWidget::cellChanged, this, &DelayDeviceParamsSet::onCellChanged);
}

/**
 * @brief 单元格内容变化事件处理，用于验证输入
 * @param row 行号
 * @param column 列号
 * @details 当表格单元格内容变化时，验证输入值是否有效
 */
void DelayDeviceParamsSet::onCellChanged(int row, int column)
{
    QTableWidget* tableWidget = qobject_cast<QTableWidget*>(sender());
    if (!tableWidget) {
        return;
    }
    
    QTableWidgetItem* item = tableWidget->item(row, column);
    if (!item) {
        return;
    }
    
    QString text = item->text();
    QString paramsName=item->data(Qt::UserRole).toString();
    if (text.isEmpty()) {
        return;
    }
    
    bool isValid = true;
    double doubleValue = 0.0;
    int intValue = 0;
    
    // 根据表格类型和列进行验证
    if (tableWidget == ui->twInitDelaySettings || tableWidget == ui->twFineDelaySettings) {
        // 初始化延迟设置表格或精延迟设置表格
        if (column == 1) {
            // 延时列：0-1000000000ns，支持三位小数
            bool ok;
            doubleValue = text.toDouble(&ok);
            if (!ok || doubleValue < 0.0 || doubleValue > 1000000000.0) {
                isValid = false;
            }
            // 确保只保留三位小数
            if (isValid) {
                item->setText(QString::number(doubleValue, 'f', 3));
            }
        } else if (column == 2) {
            // 宽度列：0-1000000000ns，不支持小数
            bool ok;
            intValue = text.toInt(&ok);
            if (!ok || intValue < 0 || intValue > 1000000000) {
                isValid = false;
            }
        }
    } else if (tableWidget == ui->twVoltageIO) {
        // 电压和IO表格
        if (column == 1) {
            // AD值列：0-5V，支持小数
            bool ok;
            doubleValue = text.toDouble(&ok);
            if (!ok || doubleValue < 0.0 || doubleValue > 5.0) {
                isValid = false;
            }
        } else if (column == 2) {
            // DA值列：0-2.5V，支持小数
            bool ok;
            doubleValue = text.toDouble(&ok);
            if (!ok || doubleValue < 0.0 || doubleValue > 2.5) {
                isValid = false;
            }
        } else if (column == 3) {
            // IO_O列：0-255，不支持小数
            bool ok;
            intValue = text.toInt(&ok);
            if (!ok || intValue < 0 || intValue > 255) {
                isValid = false;
            }
        }
    }
    
    // 如果验证失败，恢复之前的值
    if (!isValid)
    {
        item->setText(m_pDelayDevice->getParameter(paramsName).toString());
    }
}

/**
 * @brief 更新UI值为设备实际值
 * @details 从设备获取当前参数值并设置到UI控件上
 */
void DelayDeviceParamsSet::updateUIValues()
{
    if (!m_pDelayDevice) {
        return;
    }
    
    // 1. 更新初始化延迟设置表格
    for (int row = 0; row < ui->twInitDelaySettings->rowCount(); ++row) {
        // 更新延时列
        QTableWidgetItem* delayItem = ui->twInitDelaySettings->item(row, 1);
        if (delayItem) {
            QString paramName = delayItem->data(Qt::UserRole).toString();
            QVariant value = m_pDelayDevice->getParameter(paramName);
            if (value.isValid()) {
                delayItem->setText(QString::number(value.toDouble(), 'f', 3));
            }
        }
        
        // 更新宽度列
        QTableWidgetItem* widthItem = ui->twInitDelaySettings->item(row, 2);
        if (widthItem) {
            QString paramName = widthItem->data(Qt::UserRole).toString();
            QVariant value = m_pDelayDevice->getParameter(paramName);
            if (value.isValid()) {
                widthItem->setText(QString::number(value.toDouble(), 'f', 0));
            }
        }
    }
    
    // 2. 更新精延迟设置表格
    for (int row = 0; row < ui->twFineDelaySettings->rowCount(); ++row) {
        // 更新延时列
        QTableWidgetItem* delayItem = ui->twFineDelaySettings->item(row, 1);
        if (delayItem) {
            QString paramName = delayItem->data(Qt::UserRole).toString();
            QVariant value = m_pDelayDevice->getParameter(paramName);
            if (value.isValid()) {
                delayItem->setText(QString::number(value.toDouble() / 1000.0, 'f', 3)); // 转换为ns显示
            }
        }
        
        // 更新宽度列
        QTableWidgetItem* widthItem = ui->twFineDelaySettings->item(row, 2);
        if (widthItem) {
            QString paramName = widthItem->data(Qt::UserRole).toString();
            QVariant value = m_pDelayDevice->getParameter(paramName);
            if (value.isValid()) {
                widthItem->setText(QString::number(value.toDouble() / 1000.0, 'f', 3)); // 转换为ns显示
            }
        }
    }
    
    // 3. 更新电压和IO表格
    for (int row = 0; row < ui->twVoltageIO->rowCount(); ++row) {
        // DA值列
        QTableWidgetItem* daItem = ui->twVoltageIO->item(row, 2);
        if (daItem) {
            QString paramName = daItem->data(Qt::UserRole).toString();
            QVariant value = m_pDelayDevice->getParameter(paramName);
            if (value.isValid()) {
                daItem->setText(QString::number(value.toDouble(), 'f', 1));
            }
        }
        
        // IO_O列
        QTableWidgetItem* ioItem = ui->twVoltageIO->item(row, 3);
        if (ioItem) {
            QString paramName = ioItem->data(Qt::UserRole).toString();
            QVariant value = m_pDelayDevice->getParameter(paramName);
            if (value.isValid()) {
                ioItem->setText(QString::number(value.toInt()));
            }
        }
    }
    
    // 4. 更新AD值
    onUpdateADValues();
    
    // 5. 更新精延迟使能复选框
    ui->cbEnableT0->setChecked(m_pDelayDevice->getParameter(PRECISE_DELAY_ENABLE_T0).toBool());
    ui->cbEnableT1->setChecked(m_pDelayDevice->getParameter(PRECISE_DELAY_ENABLE_T1).toBool());
    ui->cbEnableT2->setChecked(m_pDelayDevice->getParameter(PRECISE_DELAY_ENABLE_T2).toBool());
}

/**
 * @brief 析构函数
 * @details 释放定时器和UI资源
 */
DelayDeviceParamsSet::~DelayDeviceParamsSet()
{
    // 停止定时器并释放资源
    if (m_pADValueTimer) {
        m_pADValueTimer->stop();
        delete m_pADValueTimer;
        m_pADValueTimer = nullptr;
    }
    
    delete ui;
}

/**
 * @brief 定时器槽函数，更新AD值
 * @details 定时从设备获取AD值并更新到UI表格中
 */
void DelayDeviceParamsSet::onUpdateADValues()
{
    // 检查设备是否有效
    if (!m_pDelayDevice) {
        return;
    }
    
    // 从设备获取AD值，使用参数宏定义
    QVariant adValue1 = m_pDelayDevice->getParameter(AD_VALUE_1);
    QVariant adValue2 = m_pDelayDevice->getParameter(AD_VALUE_2);
    
    // 确保表格有足够的行
    int rowCount = ui->twVoltageIO->rowCount();
    if (rowCount < 2) {
        ui->twVoltageIO->setRowCount(2);
    }
    
    // 更新表格中的AD值（第二列）
    if (adValue1.isValid()) {
        ui->twVoltageIO->setItem(0, 1, new QTableWidgetItem(adValue1.toString()));
    }
    
    if (adValue2.isValid()) {
        ui->twVoltageIO->setItem(1, 1, new QTableWidgetItem(adValue2.toString()));
    }
}

/**
 * @brief 初始化设置按钮点击事件处理
 * @details 收集UI中的初始化设置参数并调用设备类设置参数
 */
void DelayDeviceParamsSet::on_btnInitSettings_clicked()
{
    // 检查设备是否有效
    if (!m_pDelayDevice) {
        return;
    }
    
    // 从界面收集参数到QVariantMap
    QVariantMap paramsMap;
    
    // 设置是否保存到Flash
    paramsMap[IS_WRITE_FLASHE] = ui->cbWriteFlash->isChecked();
    
    // 收集各通道的延时和宽度参数，使用参数宏定义
    // T0上升沿
    if (ui->twInitDelaySettings->item(0, 1)) {
        quint64 delay = ui->twInitDelaySettings->item(0, 1)->text().toULongLong();
        paramsMap[RISE_EDGE_DELAY_T0] = delay;
    }
    if (ui->twInitDelaySettings->item(0, 2)) {
        quint64 width = ui->twInitDelaySettings->item(0, 2)->text().toULongLong();
        paramsMap[RISE_EDGE_WIDTH_T0] = width;
    }
    
    // T1下降沿
    if (ui->twInitDelaySettings->item(1, 1)) {
        quint64 delay = ui->twInitDelaySettings->item(1, 1)->text().toULongLong();
        paramsMap[FALL_EDGE_DELAY_T1] = delay;
    }
    if (ui->twInitDelaySettings->item(1, 2)) {
        quint64 delay = ui->twInitDelaySettings->item(1, 1)->text().toULongLong();
        paramsMap[FALL_EDGE_WIDTH_T1] = delay;
    }
    
    // T1上升沿
    if (ui->twInitDelaySettings->item(2, 1)) {
        quint64 delay = ui->twInitDelaySettings->item(2, 1)->text().toULongLong();
        paramsMap[RISE_EDGE_DELAY_T1] = delay;
    }
    if (ui->twInitDelaySettings->item(2, 2)) {
        quint64 width = ui->twInitDelaySettings->item(2, 2)->text().toULongLong();
        paramsMap[RISE_EDGE_WIDTH_T1] = width;
    }
    
    // T2下降沿
    if (ui->twInitDelaySettings->item(3, 1)) {
        quint64 delay = ui->twInitDelaySettings->item(3, 1)->text().toULongLong();
        paramsMap[FALL_EDGE_DELAY_T2] = delay;
    }
    if (ui->twInitDelaySettings->item(3, 2)) {
        quint64 width = ui->twInitDelaySettings->item(3, 2)->text().toULongLong();
        paramsMap[FALL_EDGE_WIDTH_T2] = width;
    }
    
    // T2上升沿
    if (ui->twInitDelaySettings->item(4, 1)) {
        quint64 delay = ui->twInitDelaySettings->item(4, 1)->text().toULongLong();
        paramsMap[RISE_EDGE_DELAY_T2] = delay;
    }
    if (ui->twInitDelaySettings->item(4, 2)) {
        quint64 width = ui->twInitDelaySettings->item(2, 2)->text().toULongLong();
        paramsMap[RISE_EDGE_WIDTH_T2] = width;
    }
    // 设置参数到设备，直接调用setFlashArgs方法
    bool result = m_pDelayDevice->setFlashArgs(paramsMap);
    
    // 结果提示
    if (result)
    {
        m_pDelayDevice->updateArgs(this);
        writeLog("初始化参数设置成功!",0,true);
    }
    else
    {
        writeLog("初始化参数设置失败!",2,false);
    }
}

/**
 * @brief 精延迟和使能设置按钮点击事件处理
 * @details 收集UI中的精延迟和使能设置参数并调用设备类设置参数
 */
void DelayDeviceParamsSet::on_btnSetParams_clicked()
{
    // 检查设备是否有效
    if (!m_pDelayDevice) {
        return;
    }
    
    // 从界面收集参数到QVariantMap
    QVariantMap paramsMap;
    
    // 设置精延迟通道使能，使用参数宏定义
    paramsMap[PRECISE_DELAY_ENABLE_T0] = ui->cbEnableT0->isChecked() ? 1 : 0;
    paramsMap[PRECISE_DELAY_ENABLE_T1] = ui->cbEnableT1->isChecked() ? 1 : 0;
    paramsMap[PRECISE_DELAY_ENABLE_T2] = ui->cbEnableT2->isChecked() ? 1 : 0;
    
    // 收集精延迟参数，使用参数宏定义
    // T0延迟和宽度
    if (ui->twFineDelaySettings->item(0, 1)) {
        quint64 delay = ui->twFineDelaySettings->item(0, 1)->text().toULongLong();
        paramsMap[PRECISE_DELAY_TIME_T0] = delay * 1000; // 转换为皮秒
    }
    if (ui->twFineDelaySettings->item(0, 2)) {
        quint64 width = ui->twFineDelaySettings->item(0, 2)->text().toULongLong();
        paramsMap[PRECISE_DELAY_WIDTH_T0] = width * 1000; // 转换为皮秒
    }
    
    // T1延迟和宽度
    if (ui->twFineDelaySettings->item(1, 1)) {
        quint64 delay = ui->twFineDelaySettings->item(1, 1)->text().toULongLong();
        paramsMap[PRECISE_DELAY_TIME_T1] = delay * 1000; // 转换为皮秒
    }
    if (ui->twFineDelaySettings->item(1, 2)) {
        quint64 width = ui->twFineDelaySettings->item(1, 2)->text().toULongLong();
        paramsMap[PRECISE_DELAY_WIDTH_T1] = width * 1000; // 转换为皮秒
    }
    
    // T2延迟和宽度
    if (ui->twFineDelaySettings->item(2, 1)) {
        quint64 delay = ui->twFineDelaySettings->item(2, 1)->text().toULongLong();
        paramsMap[PRECISE_DELAY_TIME_T2] = delay * 1000; // 转换为皮秒
    }
    if (ui->twFineDelaySettings->item(2, 2)) {
        quint64 width = ui->twFineDelaySettings->item(2, 2)->text().toULongLong();
        paramsMap[PRECISE_DELAY_WIDTH_T2] = width * 1000; // 转换为皮秒
    }
    
    // 设置参数到设备，直接调用setArgs方法
    bool result = m_pDelayDevice->setArgs(paramsMap);
    
    // 结果提示
    if (result)
    {
        emit m_pDelayDevice->updateArgs(this);
        writeLog("精延迟参数设置成功!",0,true);
    }
    else
    {
        writeLog("精延迟参数设置失败!",2,false);
    }
}

/**
 * @brief 鼠标按下事件处理
 * @param event 鼠标事件对象
 * @details 处理鼠标按下事件，判断是否开始拖拽窗口
 */
void DelayDeviceParamsSet::mousePressEvent(QMouseEvent *event)
{
    // 如果鼠标按下的位置在标题栏内，且不是关闭按钮
    if (ui->titleBar->geometry().contains(event->pos()) && 
        !ui->btnClose->geometry().contains(event->pos()))
    {
        m_isDragging = true;
        m_lastMousePos = event->globalPos();
    }
    QDialog::mousePressEvent(event);
}

/**
 * @brief 鼠标移动事件处理
 * @param event 鼠标事件对象
 * @details 处理鼠标移动事件，实现窗口拖拽功能
 */
void DelayDeviceParamsSet::mouseMoveEvent(QMouseEvent *event)
{
    // 如果正在拖拽，移动窗口
    if (m_isDragging)
    {
        this->move(this->pos() + event->globalPos() - m_lastMousePos);
        m_lastMousePos = event->globalPos();
    }
    QDialog::mouseMoveEvent(event);
}

/**
 * @brief 鼠标释放事件处理
 * @param event 鼠标事件对象
 * @details 处理鼠标释放事件，结束窗口拖拽
 */
void DelayDeviceParamsSet::mouseReleaseEvent(QMouseEvent *event)
{
    m_isDragging = false;
    QDialog::mouseReleaseEvent(event);
}


